from starlette.responses import StreamingResponse
from simpel_captcha import img_captcha
from simpel_captcha import captcha

from common.redis import use_redis
from celery_tasks.tasks import sms_code
from celery_tasks.tasks import async_send_email
from schemas import Response


class CaptchaService:

    @classmethod
    async def image_captcha(cls, request, uuid):
        img, text = img_captcha(byte_stream=True)
        redis = use_redis(request, 1)
        await redis.setex(uuid, 100, text)
        return StreamingResponse(img, media_type='image/jpeg')

    @classmethod
    async def sms_captcha(cls, request, mobile, image_captcha, image_captcha_id):
        redis = use_redis(request, 1)
        if (await redis.get(image_captcha_id)).lower() != image_captcha.lower():
            return Response(code=400, errmsg='图片验证码错误')

        # 是否60秒内已发送
        if await redis.get(f'sms_flag_{mobile}'):
            return Response(code=400, errmsg='频繁发送短信验证码')

        text = captcha(6)

        # 批量操作
        async with redis.pipeline(transaction=True) as pipe:
            await (pipe.setex(mobile, 300, text)
                   # 标记发送 60s 失效
                   .setex(f'sms_flag_{mobile}', 60, 1)
                   .execute()
                   )

        sms_code.delay(mobile, text, 5)
        return Response()

    @classmethod
    def send_email(cls, request, email):
        token = request.headers.get("Authorization")
        async_send_email.delay(email, f'http://localhost:8000/active_email?token={token}')
        return Response()
